<template>
  <view class="yt-file" :style="[getStyles]">
    <view ref="yt" class="hFile" :style="[getStyles]" @click="onClick">
      <slot><view class="defview" :style="[getStyles]">附件上传</view></slot>
    </view>
  </view>
</template>

<script>
import { YtjFile } from './YtjFile.js'
export default {
  name: 'yt-upload',
  props: {
    // 打印日志
    debug: { type: Boolean, default: false },
    // 自动上传
    instantly: { type: Boolean, default: false },
    // 上传接口参数设置
    option: { type: Object, default: () => {} },
    // 文件大小上限
    size: { type: Number, default: 10 },
    // 文件选择个数上限,超出后不触发点击
    count: { type: Number, default: 9 },
    // 允许上传的文件格式（多个以逗号隔开）
    formats: { type: String, default: '' },
    // input file选择限制
    accept: { type: String, default: '' },
    // 微信选择文件类型
    //all=从所有文件选择，
    //video=只能选择视频文件，
    //image=只能选择图片文件，
    //file=可以选择除了图片和视频之外的其它的文件
    wxFileType: { type: String, default: 'all' },
    // webviewID需唯一，不同窗口也不要同Id
    childId: { type: String, default: 'ytUpload' },
    // 文件选择触发面宽度
    width: { type: String, default: '100%' },
    // 文件选择触发面高度
    height: { type: String, default: '80rpx' },

    // top,left,bottom,right仅position=absolute时才需要传入
    top: { type: [String, Number], default: '' },
    left: { type: [String, Number], default: '' },
    bottom: { type: [String, Number], default: '' },
    right: { type: [String, Number], default: '' },
    // nvue不支持跟随窗口滚动
    position: {
      type: String,
      // #ifdef APP-NVUE
      default: 'absolute',
      // #endif
      // #ifndef APP-NVUE
      default: 'static',
      // #endif
    },
  },
  data() {
    return {}
  },
  watch: {
    option(v) {
      // #ifdef APP-PLUS
      this.ytFile && this.show()
      // #endif
    },
  },
  updated() {
    // #ifdef APP-PLUS
    if (this.isShow) {
      this.ytFile && this.show()
    }
    // #endif
  },
  computed: {
    getStyles() {
      let styles = {
        width: this.width,
        height: this.height,
      }
      if (this.position == 'absolute') {
        styles['top'] = this.top
        styles['bottom'] = this.bottom
        styles['left'] = this.left
        styles['right'] = this.right
        styles['position'] = 'fixed'
      }

      return styles
    },
  },
  mounted() {
    this._size = 0
    let WEBID = this.childId + new Date().getTime()
    this.ytFile = new YtjFile({
      id: WEBID,
      debug: this.debug,
      width: this.width,
      height: this.height,
      option: this.option,
      instantly: this.instantly,
      // 限制条件
      prohibited: {
        // 大小
        size: this.size,
        // 允许上传的格式
        formats: this.formats,
        // 限制选择的格式
        accept: this.accept,
        count: this.count,
      },
      onchange: this.onchange,
      onprogress: this.onprogress,
    })
    this.create()
  },
  beforeDestroy() {
    // #ifdef APP-PLUS
    this.ytFile.dom.close()
    // #endif
  },
  methods: {
    setFiles(array) {
      if (array instanceof Map) {
        for (let [key, item] of array) {
          item['progress'] = 100
          item['type'] = 'success'
          this.ytFile.files.set(key, item)
        }
      } else if (Array.isArray(array)) {
        array.forEach((item) => {
          if (item.name) {
            item['progress'] = 100
            item['type'] = 'success'
            this.ytFile.files.set(item.name, item)
          }
        })
      }
      this.onchange(this.ytFile.files)
    },
    setData() {
      this.ytFile && this.ytFile.setData(...arguments)
    },
    getDomStyles(callback) {
      // #ifndef APP-NVUE
      let view = uni.createSelectorQuery().in(this).select('.yt-file')
      view
        .fields(
          {
            size: true,
            rect: true,
          },
          ({ height, width, top, left, right, bottom }) => {
            uni
              .createSelectorQuery()
              .selectViewport()
              .scrollOffset(({ scrollTop }) => {
                return callback({
                  top: parseInt(top) + parseInt(scrollTop) + 'px',
                  left: parseInt(left) + 'px',
                  width: parseInt(width) + 'px',
                  height: parseInt(height) + 'px',
                })
              })
              .exec()
          },
        )
        .exec()
      // #endif
      // #ifdef APP-NVUE
      const dom = weex.requireModule('dom')
      dom.getComponentRect(
        this.$refs.yt,
        ({ size: { height, width, top, left, right, bottom } }) => {
          return callback({
            top: parseInt(top) + 'px',
            left: parseInt(left) + 'px',
            width: parseInt(width) + 'px',
            height: parseInt(height) + 'px',
            right: parseInt(right) + 'px',
            bottom: parseInt(bottom) + 'px',
          })
        },
      )
      // #endif
    },
    show() {
      if (this._size && this._size >= this.count) {
        return
      }
      this.isShow = true
      // #ifdef APP-PLUS
      this.ytFile &&
        this.getDomStyles((styles) => {
          this.ytFile.dom.setStyle(styles)
        })
      // #endif
      // #ifdef H5
      this.ytFile.dom.style.display = 'inline'
      // #endif
    },
    hide() {
      this.isShow = false
      // #ifdef APP-PLUS
      this.ytFile &&
        this.ytFile.dom.setStyle({
          top: '-100px',
          left: '0px',
          width: '1px',
          height: '100px',
        })
      // #endif
      // #ifdef H5
      this.ytFile.dom.style.display = 'none'
      // #endif
    },
    /**
     * 手动提交上传
     * @param {string}name 文件名称，不传则上传所有type等于waiting和fail的文件
     */
    upload(name) {
      this.ytFile && this.ytFile.upload(name)
    },
    /**
     * @returns {Map} 已选择的文件Map集
     */
    onchange(files) {
      console.log(files, '组件内的')
      this.$emit('change', files)
      this._size = files.size
      return files.size >= this.count ? this.hide() : this.show()
    },
    /**
     * @returns {object} 当前上传中的对象
     */
    onprogress(item, end = false) {
      this.$emit('progress', item)
      if (end) {
        setTimeout(() => {
          this.$emit('uploadEnd', item)
        }, 0)
      }
    },
    /**
     * 移除组件内缓存的某条数据
     * @param {string}name 文件名称,不指定默认清除所有文件
     */
    clear(name) {
      this.ytFile.clear(name)
    },
    // 创建选择器
    create() {
      // 若iOS端服务端处理不了跨域就将hybrid目录内的html放到服务端去，并将此处path改成服务器上的地址
      let path = '/uni_modules/yt-upload/hybrid/html/uploadFile.html'
      let dom = this.ytFile.create(path)
      // #ifdef H5
      this.$refs.yt.$el.appendChild(dom)
      // #endif
      // #ifndef APP-PLUS
      this.show()
      // #endif
      // #ifdef APP-PLUS
      dom.setStyle({ position: this.position })
      dom.loadURL(path)
      setTimeout(() => {
        // #ifdef APP-NVUE
        plus.webview.currentWebview().append(dom)
        // #endif
        // #ifndef APP-NVUE
        this.$root.$scope.$getAppWebview().append(dom)
        // #endif
        this.show()
      }, 500)
      // #endif
    },
    // 点击选择附件
    onClick() {
      if (this._size >= this.count) {
        this.toast(`只允许上传${this.count}个文件`)
        return
      }

      // #ifdef MP-WEIXIN
      if (!this.isShow) {
        return
      }
      let count = this.count - this._size
      this.ytFile.chooseMessageFile(this.wxFileType, count)
      // #endif
    },
    toast(msg) {
      uni.showToast({
        title: msg,
        icon: 'none',
      })
    },
  },
}
</script>

<style scoped>
.yt-file {
  display: inline-block;
}
.defview {
  background-color: #007aff;
  color: #fff;
  border-radius: 10rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 28rpx;
}
.hFile {
  position: relative;
  overflow: hidden;
}
</style>
